import React, { useState, useRef, useEffect } from 'react';
import { Alert, message} from 'antd';
import { connect, Dispatch } from 'umi';
import { LockTwoTone, UserOutlined } from '@ant-design/icons';
import ProForm, { ProFormCheckbox, ProFormText } from '@ant-design/pro-form';
import type { ProFormInstance } from '@ant-design/pro-form';
import { StateType } from '@/models/login';
import { LoginParamsType } from '@/services/login';
import { ConnectState } from '@/models/connect';
import { decodeData, encodeData, getCurrentDate, getTimeDiffOfDay } from '@/utils/commons';
import styles from './index.less';

interface LoginProps {
  dispatch: Dispatch;
  userLogin: StateType;
  submitting?: boolean;
}

interface AutoLoginType {
  userName: string;
  password: string;
  currentDate: string;
}

type AutoLoginTypeEx = Omit<AutoLoginType, 'currentDate'> & {
  autoLogin: boolean;
}

type LoginParamsTypeEx = LoginParamsType & {
  autoLogin: boolean;
}

const LoginMessage: React.FC<{
  content: string;
}> = ({ content }) => (
  <Alert
    style={{
      marginBottom: 24,
    }}
    message={content}
    type="error"
    showIcon
  />
);

/**
 * 登录页面
 */
const Login: React.FC<LoginProps> = (props) => {
  const { userLogin = {}, submitting } = props;
  const { status, type: loginType } = userLogin;
  const [type] = useState<string>('account');
  const [alt, setAlt] = useState<AutoLoginTypeEx>({
    userName: '',
    password: '',
    autoLogin: false
  });
  const formRef = useRef<
    ProFormInstance<LoginParamsTypeEx>
  >();

  useEffect(() => {
    console.info('Login.useEffect');
    const al = localStorage.getItem('al');
    if (al && al === 'IyJT') {
      const autoEncodeStr = localStorage.getItem('als');
      console.info('als', autoEncodeStr);
      if (autoEncodeStr) {
        const auto = decodeData(autoEncodeStr as string);
        const { userName, password, currentDate } = auto;
        // 判断是否过期
        const currentDateStr = getCurrentDate();
        const diff = getTimeDiffOfDay(currentDate, currentDateStr);
        if (diff > 10) {
          // 清空
          localStorage.removeItem('als');
          localStorage.removeItem('al');
        } else {
          const newAlt: AutoLoginTypeEx = {
            userName,
            password,
            autoLogin: true
          }
          setAlt({
            ...newAlt
          });
          // 重新设置表单
          formRef.current?.setFieldsValue({
            userName,
            password,
            autoLogin: true
          });
        }
      }
    }
    window.addEventListener('keydown', onKeyDown);
    return () => {
      console.info('移除监听');
      // 销毁
      window.removeEventListener('keydown', onKeyDown);
    }
  }, []);

  const onKeyDown = (e: KeyboardEvent) => {
    if (e.defaultPrevented) {
      // 如果已取消默认操作，则不应执行任何操作
      return;
    }
    var handled = false;
    if (e.code === 'Enter') {
      // 触发表单
      formRef.current!.validateFields().then(fieldsValue => {
        console.info(fieldsValue);
        handleSubmit(fieldsValue);
        handled = true;
      }).catch();
    }
    if (handled) {
      // 如果事件已处理，则禁止“双重操作”
      e.preventDefault();
    }
  }

  const handleSubmit = (values: LoginParamsTypeEx) => {
    // 判断是够勾选了自动登录
    // 勾选了，则将用户名密码保存在本地，
    // 下次打开页面判断本地是够保存了用户名密码，且保存时间至今多久
    const autoLogin = formRef.current?.getFieldValue('autoLogin');
    if (!autoLogin) {
      // 未勾选，清除本地记录
      localStorage.removeItem('als');
      localStorage.removeItem('al');
    } else {
      const auto: AutoLoginType = {
        userName: values.userName,
        password: values.password,
        currentDate: getCurrentDate()
      }
      const autoEncodeStr = encodeData(auto);
      localStorage.setItem('als', autoEncodeStr);
      localStorage.setItem('al', 'IyJT');
    }
    const { dispatch } = props;
    dispatch({
      type: 'login/login',
      payload: { ...values, type },
    });
  };
  const forgotPassword = () => {
    message.info('请联系管理员重置密码');
  };
  const { userName, password, autoLogin = false } = alt;
  return (
    <div className={styles.main}>
      <ProForm<LoginParamsTypeEx>
        initialValues={{
          autoLogin
        }}
        submitter={{
          render: (_, dom) => dom.pop(),
          submitButtonProps: {
            loading: submitting,
            size: 'large',
            style: {
              width: '100%',
            },
          },
        }}
        onFinish={async (values: LoginParamsTypeEx) => {
          handleSubmit(values);
        }}
        formRef={formRef}
      >
        {status === 'error' && loginType === 'account' && !submitting && (
          <LoginMessage
            content='账户或密码错误！'
          />
        )}
        {type === 'account' && (
          <>
            <ProFormText
              name="userName"
              fieldProps={{
                size: 'large',
                prefix: <UserOutlined className={styles.prefixIcon} />,
              }}
              placeholder='用户名: admin or user'
              rules={[
                {
                  required: true,
                  message: '请输入用户名！',
                },
              ]}
              initialValue={userName}
            />
            <ProFormText.Password
              name="password"
              fieldProps={{
                size: 'large',
                prefix: <LockTwoTone className={styles.prefixIcon} />,
              }}
              placeholder='密码: ant.design'
              rules={[
                {
                  required: true,
                  message: (
                    '请输入密码！'
                  ),
                },
              ]}
              initialValue={password}
            />
          </>
        )}
        <div
          style={{
            marginBottom: 24,
          }}
        >
          <ProFormCheckbox noStyle name="autoLogin">
            记住我
          </ProFormCheckbox>
          <a
            style={{
              float: 'right',
            }}
            onClick={() => forgotPassword()}
          >
            忘记密码
          </a>
        </div>
      </ProForm>
    </div>
  );
};

export default connect(({ login, loading }: ConnectState) => ({
  userLogin: login,
  submitting: loading.effects['login/login'],
}))(Login);
